/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#define LOG_TAG "lemon"

#include <errno.h>
#include <malloc.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <log/log.h>

#include <hardware/bearpi.h>
#include <hardware/hardware.h>
#include "mpu_angle_thread.h"

bear_notify_t gNotify; //定义全局函数变量

void set_notify(bear_notify_t notify){
    gNotify = notify;
}


static int bearpi_close(hw_device_t *dev){
    bear_device_t* bear_device = (struct bear_device*) dev;
    if(bear_device){
        close(bear_device->fd);
        free(bear_device);
        return 0;
    }else{
        return -1;
    }
}

/*设备寄存器读写接口*/
static int bearpi_get_val(struct bear_device* dev, int *val){

    if(!dev){
        ALOGE("bearpi device null pointer");
        return -EFAULT;
    }

    if(!val){
        ALOGE("bearpi val null pointer");
        return -EFAULT;
    }

    read(dev->fd, val, sizeof(*val));
    ALOGD(" bearpi get value = %d", *val);
    return 0;

}

static int bearpi_set_val(struct bear_device* dev, int val){
    if(!dev){
        ALOGE("bearpi device null pointer");
        return -EFAULT;
    }

    write(dev->fd, &val, sizeof(val));
    ALOGD("bearpi set val success !");
    return 0;
}

static int set_notify_callback(struct bear_device __unused *dev, bear_notify_t notify){
    dev->notify=notify;
    set_notify(notify);
    ALOGD("%s",__func__ );
    return 0;
}

static uint64_t bearpi_start_get_angle(){
    ALOGD("%s",__func__ );
    start_process();
    return 0;
}

static uint64_t bearpi_stop_get_angle(){
    ALOGD("%s",__func__ );
    stop_process();
    return 0;
}

static  uint64_t bearpi_test(struct bear_device __unused *dev){
    ALOGD("%s:start ",__func__ );
    bear_msg_t msg;
    bear_acquired_t acquired;

    msg.type = BEAR_ACQUIRED;
    acquired.acquired_info = BEAR_ACQUIRED_GOOD;
    msg.data.acquired = acquired;
    gNotify(&msg);
    ALOGD("%s: end ",__func__ );
    return 0;
}

static int bearpi_open(const hw_module_t* module, const char __unused *id, hw_device_t** device){
    if(device == NULL){
        ALOGE("NULL device on open");
        return -EINVAL;
    }
    ALOGD("%s: start ",__func__ );

    bear_device_t *dev = malloc(sizeof(bear_device_t));

    if(!dev){
        ALOGE("Failed to alloc space for bearpi");
        return -EFAULT;
    }

    memset(dev, 0, sizeof(bear_device_t));

    dev->common.tag = HARDWARE_DEVICE_TAG;
    dev->common.version = BEAR_MODULE_API_VERSION_1_0;
    dev->common.module = (struct hw_module_t*) module;
    dev->common.close = bearpi_close;

    dev->test= bearpi_test;
    dev->set_notify = set_notify_callback;
    dev->notify=NULL;
    dev->set_val = bearpi_set_val;
    dev->get_val = bearpi_get_val;
    dev->start_get_angle = bearpi_start_get_angle;
    dev->stop_get_angle = bearpi_stop_get_angle;

    *device = (hw_device_t*) dev;
    ALOGD("%s: end",__func__ );
    return 0;
}


static struct hw_module_methods_t bearpi_module_methods = {
        .open = bearpi_open,
};

bear_module_t HAL_MODULE_INFO_SYM={
        .common = {
                .tag                = HARDWARE_MODULE_TAG,
                .module_api_version = BEAR_MODULE_API_VERSION_1_0,
                .hal_api_version    = HARDWARE_HAL_API_VERSION,
                .id                 = BEAR_HARDWARE_MODULE_ID,
                .name               = "bear HAL module",
                .author             = "fht",
                .methods            = &bearpi_module_methods,
        },
};
